package com.ruoyi.product.service.impl;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

import cn.hutool.core.collection.CollUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ruoyi.common.constant.BizCodeConstants;
import com.ruoyi.common.constant.CommonConst;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.exception.BusinessException;
import com.ruoyi.common.json.JSONObject;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.IdGenerator;
import com.ruoyi.product.domain.Product;
import com.ruoyi.product.domain.ProductPrice;
import com.ruoyi.product.dto.*;
import com.ruoyi.product.mapper.ProductMapper;
import com.ruoyi.product.mapper.ProductPriceMapper;
import org.apache.commons.compress.utils.Lists;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.product.mapper.ProductCartMapper;
import com.ruoyi.product.domain.ProductCart;
import com.ruoyi.product.service.IProductCartService;
import com.ruoyi.common.core.text.Convert;

import javax.validation.constraints.NotNull;

/**
 * 购物车Service业务层处理
 *
 * @author tanfp
 * @date 2021-01-02
 */
@Service
public class ProductCartServiceImpl implements IProductCartService {
    @Autowired
    private ProductCartMapper productCartMapper;

    @Autowired
    private ProductMapper productMapper;

    @Autowired
    private ProductPriceMapper productPriceMapper;

    @Override
    public AjaxResult addCart(List<ProductCartAddParam> param, Long userId, Long productId) {
        if (Objects.isNull(productId)) {
            return AjaxResult.error(BizCodeConstants.PRODUCT_ID_NOT_NULL, "商品id不能为空");
        }

        // 判断商品是否存在
        // 查询商品是否存在
        Product queryProduct = new Product();
        queryProduct.setKeyId(productId);
        queryProduct.setDelStatus(CommonConst.DEL_FALSE);
        List<Product> products = productMapper.selectProductList(queryProduct);
        if (CollUtil.isEmpty(products)) {
            return AjaxResult.error(BizCodeConstants.PRODUCT_NOT_EXIST, "商品不存在");
        }

        List<String> priceIds = param.stream().map(ProductCartAddParam::getPriceId).distinct().collect(Collectors.toList());
        List<ProductCart> existProductCarts = productCartMapper.selectByPriceIds(productId, userId, priceIds);
        // 从参数中找出哪些是已经存在的，哪些是还不存在的
        List<Long> existPriceIds = existProductCarts.stream().map(ProductCart::getPriceId).distinct().collect(Collectors.toList());
        List<ProductCartAddParam> noExistProductCarts = param.stream().filter(p -> !existPriceIds.contains(Long.valueOf(p.getPriceId()))).distinct().collect(Collectors.toList());

        // 需要新增的
        if (CollUtil.isNotEmpty(noExistProductCarts)) {
            noExistProductCarts.forEach(n -> {
                ProductCart cartInsert = new ProductCart();
                cartInsert.setAddNum(n.getAddNum());
                cartInsert.setDelStatus(CommonConst.DEL_FALSE);
                cartInsert.setProductId(productId);
                cartInsert.setUserId(userId);
                cartInsert.setPriceId(Long.valueOf(n.getPriceId()));
                cartInsert.setKeyId(IdGenerator.getId());
                cartInsert.setCreateBy(String.valueOf(userId));
                cartInsert.setCreateTime(new Date());
                cartInsert.setUpdateBy(cartInsert.getCreateBy());
                cartInsert.setUpdateTime(cartInsert.getCreateTime());
                cartInsert.setCartSelectStatus(1);
                productCartMapper.insertProductCart(cartInsert);
            });
        }

        // 需要修改的
        if (CollUtil.isNotEmpty(existProductCarts)) {
            existProductCarts.forEach(e -> {
                ProductCartAddParam productCartAddParam = param.stream().filter(p -> Long.valueOf(p.getPriceId()).equals(e.getPriceId())).findFirst().get();
                if (productCartAddParam.getAddNum().equals(0)) {
                    // 需要删除
                    e.setDelStatus(CommonConst.DEL_TRUE);
                }
                e.setAddNum(productCartAddParam.getAddNum());
                e.setUpdateTime(new Date());
                e.setUpdateBy(String.valueOf(userId));
                productCartMapper.updateProductCart(e);
            });
        }

        return AjaxResult.success();
    }

    @Override
    public AjaxResult removeCart(Long userId, List<String> productIds) {
        productCartMapper.removeCart(userId, productIds);
        return AjaxResult.success();
    }

    @Override
    public AjaxResult queryCart(Long userId) {
        // 获取这个用户的所有加入购物车中上架的商品
        List<ProductCart> productCarts = productCartMapper.selectProductCartListByUserId(userId);

        // 获取商品id列表
        List<Long> productIds = productCarts.stream().map(ProductCart::getProductId).distinct().collect(Collectors.toList());
        if (CollUtil.isEmpty(productIds)) {
            return AjaxResult.success();
        }
        List<CartResDTO> cartResDTOS = productCartMapper.selectProductListByIds(productIds);
        cartResDTOS = setDefaultPrice2DTO(cartResDTOS, productCarts);
        cartResDTOS = setUpdateTime2DTO(cartResDTOS, productCarts);

        return AjaxResult.success(cartResDTOS);
    }

    @Override
    public AjaxResult queryCart(Long userId, PageQuery pageQuery) {
        PageHelper.startPage(pageQuery.getPageNum(), pageQuery.getPageSize());
        // 获取这个用户的所有加入购物车中上架的商品
        List<ProductCart> productCarts = productCartMapper.selectProductCartListByUserId(userId);

        // 获取商品id列表
        List<Long> productIds = productCarts.stream().map(ProductCart::getProductId).distinct().collect(Collectors.toList());
        if (CollUtil.isEmpty(productIds)) {
            return AjaxResult.success();
        }
        List<CartResDTO> cartResDTOS = productCartMapper.selectProductListByIds(productIds);
        cartResDTOS = setDefaultPrice2DTO(cartResDTOS, productCarts);
        cartResDTOS = setUpdateTime2DTO(cartResDTOS, productCarts);

        PageInfo<CartResDTO> pageInfo = PageInfo.of(cartResDTOS);
        return AjaxResult.success(pageInfo);
    }

    @Override
    public AjaxResult queryOrderCart(Long userId) {
        // 获取这个用户的所有加入购物车中上架的商品
        List<ProductCart> productCarts = productCartMapper.selectProductCartOrdersListByUserId(userId);

        // 获取商品id列表
        List<Long> productIds = productCarts.stream().map(ProductCart::getProductId).distinct().collect(Collectors.toList());
        if (CollUtil.isEmpty(productIds)) {
            return AjaxResult.success();
        }
        List<CartResDTO> cartResDTOS = productCartMapper.selectProductListByIds(productIds);
        cartResDTOS = setDefaultPrice2DTO(cartResDTOS, productCarts);
        cartResDTOS = setUpdateTime2DTO(cartResDTOS, productCarts);

        return AjaxResult.success(cartResDTOS);
    }

    @Override
    public List<ProductCart> selectProductCartOrdersListByUserId(Long userId) {
        return productCartMapper.selectProductCartOrdersListByUserId(userId);
    }

    @Override
    public int deleteProductCartByOrdersProductIds(Long userId, List<String> productIds) {
        return productCartMapper.deleteProductCartByOrdersProductIds(userId,productIds);
    }

    @Override
    public AjaxResult queryCartNum(Long userId) {
        if (Objects.isNull(userId)) {
            return AjaxResult.success(0);
        }
        // 获取该用户所有购物车商品
        ProductCart query = new ProductCart();
        query.setUserId(userId);
        query.setDelStatus(CommonConst.DEL_FALSE);
        List<ProductCart> productCarts = productCartMapper.selectProductCartList(query);
        if (CollUtil.isEmpty(productCarts)) {
            return AjaxResult.success(0);
        }
        int size = productCarts.stream().collect(Collectors.groupingBy(ProductCart::getProductId)).keySet().size();
        return AjaxResult.success(size);
    }

    private List<CartResDTO> setUpdateTime2DTO(List<CartResDTO> cartResDTOS, List<ProductCart> productCarts) {
        cartResDTOS.forEach(c -> {
            Long productId = c.getProductId();
            ProductCart productCart = productCarts.stream().filter(p -> productId.equals(p.getProductId())).findFirst().orElse(new ProductCart());
            c.setUpdateTime(productCart.getUpdateTime());
            c.setSelectFlag(productCart.getCartSelectStatus());
            c.setCartId(productCart.getKeyId());
        });
        return cartResDTOS.stream().sorted(Comparator.comparing(CartResDTO::getUpdateTime).reversed()).collect(Collectors.toList());
    }

    private List<CartResDTO> setDefaultPrice2DTO(List<CartResDTO> cartResDTOS, List<ProductCart> productCarts) {
        if (CollUtil.isEmpty(cartResDTOS)) {
            return Lists.newArrayList();
        }
        List<Long> productIds = cartResDTOS.stream().map(CartResDTO::getProductId).distinct().collect(Collectors.toList());
        // 通过产品列表获取价格列表
        List<ProductPriceDTO> productPriceList = productPriceMapper.selectProductPriceListByProductIds(productIds);

        // 将价格根据商品id进行分组
        Map<Long, List<ProductPriceDTO>> priceMap = productPriceList.stream().collect(Collectors.groupingBy(ProductPriceDTO::getProductId));
        cartResDTOS.forEach(p -> {
            List<ProductPriceDTO> priceDTOS = priceMap.get(p.getProductId());
            List<ProductCartPriceDTO> productPriceDTOS = covert2CartPrice(priceDTOS, productCarts);
            if (CollUtil.isNotEmpty(productPriceDTOS)) {
                // 排序
                productPriceDTOS = productPriceDTOS.stream().sorted(Comparator.comparing(ProductCartPriceDTO::getSort)).collect(Collectors.toList());
                p.setPriceDTO(productPriceDTOS);
            } else {
                p.setPriceDTO(Lists.newArrayList());
            }
        });
        return cartResDTOS;
    }

    public List<ProductCartPriceDTO> covert2CartPrice (List<ProductPriceDTO> priceDTOS, List<ProductCart> productCarts) {
        if (CollUtil.isEmpty(priceDTOS)) {
            return CollUtil.newArrayList();
        }
        // 购物车价格列表
        return priceDTOS.stream().map(p -> {
            ProductCartPriceDTO priceDTO = new ProductCartPriceDTO();
            BeanUtils.copyProperties(p, priceDTO);

            ProductCart productCart = productCarts.stream().filter(c -> p.getProductId().equals(c.getProductId()) && c.getPriceId().equals(p.getPriceId())).findFirst().orElse(new ProductCart());
            if (Objects.isNull(productCart) || Objects.isNull(productCart.getAddNum())) {
                priceDTO.setAddNum(0);
            } else{
                priceDTO.setAddNum(productCart.getAddNum());
            }
            return priceDTO;
        }).collect(Collectors.toList());
    }

    /**
     * 查询购物车
     *
     * @param keyId 购物车ID
     * @return 购物车
     */
    @Override
    public ProductCart selectProductCartById(Long keyId) {
        return productCartMapper.selectProductCartById(keyId);
    }

    /**
     * 查询购物车列表
     *
     * @param productCart 购物车
     * @return 购物车
     */
    @Override
    public List<ProductCart> selectProductCartList(ProductCart productCart) {
        return productCartMapper.selectProductCartList(productCart);
    }

    /**
     * 新增购物车
     *
     * @param productCart 购物车
     * @return 结果
     */
    @Override
    public int insertProductCart(ProductCart productCart) {
        productCart.setCreateTime(DateUtils.getNowDate());
        return productCartMapper.insertProductCart(productCart);
    }

    /**
     * 修改购物车
     *
     * @param productCart 购物车
     * @return 结果
     */
    @Override
    public int updateProductCart(ProductCart productCart) {
        productCart.setUpdateTime(DateUtils.getNowDate());
        return productCartMapper.updateProductCart(productCart);
    }

    @Override
    public BigDecimal updateProductCartNum(Long userId, Long cartId, Integer num) {
        ProductCart productCart1 = new ProductCart();
        productCart1.setKeyId(cartId);
        ProductCart pp = productCartMapper.selectProductCartList(productCart1).get(0);
        pp.setAddNum(num);
        productCartMapper.updateProductCart(pp);

        ProductCart productCart = new ProductCart();
        productCart.setUserId(userId);
        productCart.setDelStatus(0);
        List<ProductCart> lst = productCartMapper.selectProductCartList(productCart);
        boolean allSelected = true;
        BigDecimal sumPrice = new BigDecimal(0.00);
        for(ProductCart p : lst){
            if(p.getCartSelectStatus() < 1){
                allSelected = false;
            }else{
                ProductPrice price = productPriceMapper.selectProductPriceById(p.getPriceId());
                sumPrice = sumPrice.add(price.getProductPrice().multiply(new BigDecimal(p.getAddNum())));
            }
        }

        return  sumPrice;
    }

    @Override
    public AjaxResult updateAllStatus(Long userId, Integer selectFlag) {
        productCartMapper.updateAllStatus(userId,selectFlag);
        return AjaxResult.success();
    }

    @Override
    public AjaxResult updateProductCartStatus(Long userId,Integer selectFlag,List<Long> cartIds) {
        productCartMapper.updateStatus(selectFlag,cartIds);
        ProductCart productCart = new ProductCart();
        productCart.setUserId(userId);
        productCart.setDelStatus(0);
        List<ProductCart> lst = productCartMapper.selectProductCartList(productCart);
        boolean allSelected = true;
        BigDecimal sumPrice = new BigDecimal(0.00);
        for(ProductCart p : lst){
            if(p.getCartSelectStatus() < 1){
                allSelected = false;
            }else{
                ProductPrice price = productPriceMapper.selectProductPriceById(p.getPriceId());
                sumPrice = sumPrice.add(price.getProductPrice().multiply(new BigDecimal(p.getAddNum())));
            }
        }
        JSONObject object = new JSONObject();
        object.put("allSelected",allSelected);
        object.put("sum",sumPrice);
        return AjaxResult.success(object);
    }

    /**
     * 删除购物车对象
     *
     * @param ids 需要删除的数据ID
     * @return 结果
     */
    @Override
    public int deleteProductCartByIds(String ids) {
        return productCartMapper.deleteProductCartByIds(Convert.toStrArray(ids));
    }

    /**
     * 删除购物车信息
     *
     * @param keyId 购物车ID
     * @return 结果
     */
    @Override
    public int deleteProductCartById(Long keyId) {
        return productCartMapper.deleteProductCartById(keyId);
    }

}
